﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using IsmsExplorer.Infrastructure.DomainBase;

namespace IsmsExplorer.Infrastructure.RepositoryFramework {
    public abstract class RepositoryBase<T> : IRepository<T>, IUnitOfWorkRepository where T : EntityBase {
        // Optional UnitOfWork, injected during creation.
        protected IUnitOfWork _unitOfWork;

        public RepositoryBase() : this(null) {
        }

        public RepositoryBase(IUnitOfWork unitOfWork) {
            this._unitOfWork = unitOfWork;
        }

        #region IRepository<T> implementation
        
        public abstract T FindBy(object key);
        public abstract IList<T> FindAll();

        public virtual void Add(T item) {
            if (_unitOfWork != null) {
                _unitOfWork.RegisterAdded(item, this);
            }
        }

        public virtual T this[object key] {
            get {
                return FindBy(key);
            }
            set {
                if (FindBy(key) == null) {
                    Add(value);
                } else {
                    if (_unitOfWork != null) {
                        _unitOfWork.RegisterUpdated(value, this);
                    }
                }
            }
        }

        public virtual void Remove(T item) {
            if (_unitOfWork != null) {
                _unitOfWork.RegisterDeleted(item, this);
            }
        }

        public IUnitOfWork UnitOfWork {
            get { return _unitOfWork; }
        }

        #endregion IRepository<T> implementation

        #region IUnitOfWorkRepository implementation

        public void PersistNewItem(EntityBase item) {
            PersistNewItem((T)item);
        }

        public void PersistUpdatedItem(EntityBase item) {
            PersistUpdatedItem((T)item);
        }

        public void PersistDeletedItem(EntityBase item) {
            PersistDeletedItem((T)item);
        }

        #endregion IUnitOfWorkRepository implementation

        protected abstract void PersistNewItem(T item);
        protected abstract void PersistUpdatedItem(T item);
        protected abstract void PersistDeletedItem(T item);

    } // end public abstract class RepositoryBase<T> : IRepository<T>, IUnitOfWorkRepository
}
